package com.komorebi.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.komorebi.entity.SysMenu;
import com.komorebi.entity.SysRole;
import com.komorebi.entity.SysUser;
import com.komorebi.mapper.SysUserMapper;
import com.komorebi.mapper.SysUserRoleMapper;
import com.komorebi.service.SysMenuService;
import com.komorebi.service.SysRoleService;
import com.komorebi.service.SysUserRoleService;
import com.komorebi.service.SysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.komorebi.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author komorebi
 * @since 2021-11-19
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    SysUserMapper  sysUserMapper;
    @Autowired
    SysRoleService sysRoleService;
    @Autowired
    SysMenuService sysMenuService;
    @Autowired
    RedisUtil  redisUtil;

    @Override
    public SysUser getByUserName(String username) {
        return getOne(new QueryWrapper<SysUser>().eq("username",username));
    }

    @Override
    public String getUserAuthority(Long userId) {
        String username = sysUserMapper.selectById(userId).getUsername();
        String authority = "";
        //先查缓存
        if(redisUtil.hasKey("GrantedAuthority:"+username)){
            authority = (String) redisUtil.get("GrantedAuthority:"+username);
        }else{
            //获取角色
            //insql使用
            //select * from sys_role where id in (select role_id from sys_user_role where user_id =  userId)
            List<SysRole> roles = sysRoleService.list(new QueryWrapper<SysRole>()
                    .inSql("id", "select role_id from sys_user_role where user_id = " + userId));


            if(roles.size() > 0){
                //将roles的code用逗号连接,code里面是角色信息
                String roleCodes = roles.stream().map(r -> "ROLE_"+r.getCode()).collect(Collectors.joining(","));
                authority = roleCodes.concat(",");

            }
            //获取擦弹操作权限
            List<Long> menuIds = sysUserMapper.getNavMenuIds(userId);
            if(menuIds.size() > 0){
                List<SysMenu> menus = sysMenuService.listByIds(menuIds);
                String menuPerms = menus.stream().map(m -> m.getPerms()).collect(Collectors.joining(","));
                authority = authority.concat(menuPerms);
            }
            redisUtil.set("GrantedAuthority:"+username,authority,60 * 60);
        }

        return authority;
    }

    //当用户权限改变时清空缓存
    @Override
    public void clearUserAuthorityInfo(String username) {
        redisUtil.del("GrantedAuthority:"+username);
    }
    //当用户的角色信息改变时清空缓存
    @Override
    public void clearUserAuthorityInfoByRoleId(Long roleId) {
        List<SysUser> sysUsers = this.list(new QueryWrapper<SysUser>()
                .inSql("id", "select user_id from sys_user_role where role_id = " + roleId));

        sysUsers.forEach(u -> {
            this.clearUserAuthorityInfo(u.getUsername());
        });
    }
    //当用户的菜单改变时清空缓存
    @Override
    public void clearUserAuthorityInfoByMenuId(Long menuId) {
        List<SysUser> sysUsers = sysUserMapper.listByMenuId(menuId);

        sysUsers.forEach(u -> {
            this.clearUserAuthorityInfo(u.getUsername());
        });
    }
}
